package com.black.utils.converter;


import java.math.BigInteger;

/**
 * @author ylx
 */
public class BaseConverter {

    /**
     * 十进制转二进制
     *
     * @param decimal 十进制数
     * @return 二进制字符串
     */
    public static String decimalToBinary(int decimal) {
        StringBuilder binary = new StringBuilder(Integer.toBinaryString(decimal));
        while (binary.length() < 32) {
            binary.insert(0, "0");
        }
        return binary.toString();
    }

    /**
     * 十进制转二进制
     *
     * @param decimal 十进制数
     * @return 二进制字符串
     */
    public static String decimalToBinary(long decimal) {
        StringBuilder binary = new StringBuilder(Long.toBinaryString(decimal));
        while (binary.length() < 64) {
            binary.insert(0, "0");
        }
        return binary.toString();
    }

    /**
     * 十进制转二进制
     *
     * @param decimal 十进制数
     * @return 二进制字符串
     */
    public static String decimalToBinary(short decimal) {
        StringBuilder binary = new StringBuilder(Integer.toBinaryString(decimal & 0xFFFF));
        while (binary.length() < 16) {
            binary.insert(0, "0");
        }
        return binary.toString();
    }

    /**
     * 十进制转二进制
     *
     * @param decimal 十进制数
     * @return 二进制字符串
     */
    public static String decimalToBinary(byte decimal) {
        StringBuilder binary = new StringBuilder(Integer.toBinaryString(decimal & 0xFF));
        while (binary.length() < 8) {
            binary.insert(0, "0");
        }
        return binary.toString();
    }

    public static String decimalToBinary(Number decimal) {
        if (decimal instanceof Integer) {
            return decimalToBinary(decimal.intValue());
        } else if (decimal instanceof Long) {
            return decimalToBinary(decimal.longValue());
        } else if (decimal instanceof Short) {
            return decimalToBinary(decimal.shortValue());
        } else if (decimal instanceof Byte) {
            return decimalToBinary(decimal.byteValue());
        } else {
            throw new IllegalArgumentException("不支持的类型");
        }
    }

    /**
     * 十进制转八进制
     *
     * @param decimal 十进制数
     * @return 八进制字符串
     */
    public static String decimalToOctal(int decimal) {
        StringBuilder octal = new StringBuilder(Integer.toOctalString(decimal));
        while (octal.length() < 11) {
            octal.insert(0, "0");
        }
        return octal.toString();
    }

    /**
     * 十进制转八进制
     *
     * @param decimal 十进制数
     * @return 八进制字符串
     */
    public static String decimalToOctal(long decimal) {
        StringBuilder octal = new StringBuilder(Long.toOctalString(decimal));
        while (octal.length() < 22) {
            octal.insert(0, "0");
        }
        return octal.toString();
    }

    /**
     * 十进制转八进制
     *
     * @param decimal 十进制数
     * @return 八进制字符串
     */
    public static String decimalToOctal(short decimal) {
        StringBuilder octal = new StringBuilder(Integer.toOctalString(decimal & 0xFFFF));
        while (octal.length() < 5) {
            octal.insert(0, "0");
        }
        return octal.toString();
    }

    /**
     * 十进制转八进制
     *
     * @param decimal 十进制数
     * @return 八进制字符串
     */
    public static String decimalToOctal(byte decimal) {
        StringBuilder octal = new StringBuilder(Integer.toOctalString(decimal & 0xFF));
        while (octal.length() < 3) {
            octal.insert(0, "0");
        }
        return octal.toString();
    }

    public static String decimalToOctal(Number decimal) {
        if (decimal instanceof Integer) {
            return decimalToOctal(decimal.intValue());
        } else if (decimal instanceof Long) {
            return decimalToOctal(decimal.longValue());
        } else if (decimal instanceof Short) {
            return decimalToOctal(decimal.shortValue());
        } else if (decimal instanceof Byte) {
            return decimalToOctal(decimal.byteValue());
        } else {
            throw new IllegalArgumentException("不支持的类型");
        }
    }

    /**
     * 十进制转十六进制
     *
     * @param decimal 十进制数
     * @return 十六进制字符串
     */
    public static String decimalToHex(int decimal) {
        StringBuilder hex = new StringBuilder(Integer.toHexString(decimal));
        while (hex.length() < 8) {
            hex.insert(0, "0");
        }
        return hex.toString().toUpperCase();
    }

    /**
     * 十进制转十六进制
     *
     * @param decimal 十进制数
     * @return 十六进制字符串
     */
    public static String decimalToHex(long decimal) {
        StringBuilder hex = new StringBuilder(Long.toHexString(decimal));
        while (hex.length() < 16) {
            hex.insert(0, "0");
        }
        return hex.toString().toUpperCase();
    }

    /**
     * 十进制转十六进制
     *
     * @param decimal 十进制数
     * @return 十六进制字符串
     */
    public static String decimalToHex(short decimal) {
        StringBuilder hex = new StringBuilder(Integer.toHexString(decimal & 0xFFFF));
        while (hex.length() < 4) {
            hex.insert(0, "0");
        }
        return hex.toString().toUpperCase();
    }

    /**
     * 十进制转十六进制
     *
     * @param decimal 十进制数
     * @return 十六进制字符串
     */
    public static String decimalToHex(byte decimal) {
        StringBuilder hex = new StringBuilder(Integer.toHexString(decimal & 0xFF));
        while (hex.length() < 2) {
            hex.insert(0, "0");
        }
        return hex.toString().toUpperCase();
    }

    public static String decimalToHex(Number decimal) {
        if (decimal instanceof Integer) {
            return decimalToHex(decimal.intValue());
        } else if (decimal instanceof Long) {
            return decimalToHex(decimal.longValue());
        } else if (decimal instanceof Short) {
            return decimalToHex(decimal.shortValue());
        } else if (decimal instanceof Byte) {
            return decimalToHex(decimal.byteValue());
        } else {
            throw new IllegalArgumentException("不支持的类型");
        }
    }


    /**
     * 十进制转任意进制
     *
     * @param decimal 十进制数
     * @param radix   目标进制基数
     * @return 转换后的进制字符串
     */
    public static String decimalToArbitraryBase(Number decimal, int radix) {
        if (radix < 2 || radix > 36) {
            throw new IllegalArgumentException("radix must be between 2 and 36");
        }
        switch (radix) {
            case 2:
                return decimalToBinary(decimal);
            case 8:
                return decimalToOctal(decimal);
            case 16:
                return decimalToHex(decimal);
            default:
                if (decimal instanceof Integer) {
                    return Integer.toString(decimal.intValue(), radix).toUpperCase();
                } else if (decimal instanceof Long) {
                    return Long.toString(decimal.longValue(), radix).toUpperCase();
                } else if (decimal instanceof Short) {
                    return Integer.toString(decimal.shortValue() & 0xFFFF, radix).toUpperCase();
                } else if (decimal instanceof Byte) {
                    return Integer.toString(decimal.byteValue() & 0xFF, radix).toUpperCase();
                } else {
                    throw new IllegalArgumentException("不支持的类型");
                }
        }
    }

    /**
     * 转任意进制
     * 该方法不适合byte 与 short 类型
     *
     * @param number    任意进制字符串
     * @param fromRadix 原进制
     * @param toRadix   目标进制
     * @return 转换后的进制字符串
     */
    public static String fromToArbitraryBase(String number, int fromRadix, int toRadix) {
        Number decimal = arbitraryBaseToDecimal(number, fromRadix);
        return decimalToArbitraryBase(decimal, toRadix);
    }

    /**
     * 二进制转十进制
     *
     * @param binary 二进制字符串
     * @return 十进制数
     */
    public static Number binaryToDecimal(String binary) {
        return arbitraryBaseToDecimal(binary, 2);
    }

    /**
     * 八进制转十进制
     *
     * @param octal 八进制字符串
     * @return 十进制数
     */
    public static Number octalToDecimal(String octal) {
        return arbitraryBaseToDecimal(octal, 8);
    }

    /**
     * 十六进制转十进制
     *
     * @param hex 十六进制字符串
     * @return 十进制数
     */
    public static Number hexToDecimal(String hex) {
        return arbitraryBaseToDecimal(hex, 16);
    }

    /**
     * 任意进制转十进制
     *
     * @param number 进制数的字符串表示
     * @param radix  进制基数（例如，2, 8, 16等）
     * @return 十进制数
     */
    public static Number arbitraryBaseToDecimal(String number, int radix) {
        // 检查进制基数
        if (radix < 2 || radix > 36) {
            throw new IllegalArgumentException("radix must be between 2 and 36");
        }
        // 去掉前缀
        number = number.toUpperCase();
        if (number.startsWith("0X")) {
            number = number.substring(2);
        }
        if (number.startsWith("0B")) {
            number = number.substring(2);
        }
        // 去掉前导0
        while (number.startsWith("0")) {
            number = number.substring(1);
        }
        // 判断是否超过int范围
        String maxIntRadix = decimalToArbitraryBase(Integer.MAX_VALUE, radix);
        if ((number.compareTo(maxIntRadix) > 0 && !number.startsWith("1")) || number.length() > maxIntRadix.length()) {
            // 超过int范围，转换为long
            return new BigInteger(number, radix).longValue();
        }
        return Integer.parseInt(number, radix);
    }

    public static int intValue(String number, int radix) {
        return arbitraryBaseToDecimal(number, radix).intValue();
    }

    public static long longValue(String number, int radix) {
        return arbitraryBaseToDecimal(number, radix).longValue();
    }

    public static short shortValue(String number, int radix) {
        return arbitraryBaseToDecimal(number, radix).shortValue();
    }

    public static byte byteValue(String number, int radix) {
        return arbitraryBaseToDecimal(number, radix).byteValue();
    }
}
